perm filename RPIDV.MAC[IP,SYS] blob
sn#680216 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-INET>RPIDV.MAC.40301 29-Jan-82 15:14:50, Edit by CLYNN
; Updated for IP release 3
SEARCH INPAR,TCPPAR,IMPPAR,PROLOG
TTITLE RPIDV
SUBTTL Raw Packet Interface Driver, William W. Plummer, 2JAN78
COMMENT !
This module provides service for a BBN IMP10 interface.
The packets sent and received via this
interface are Internet packets without any local header. The
local header will be supplied by the gateway in the device
to which the interface is connected.
To cause the gateway to use the RPI device, the switch INTSCR should
be set non-zero. This will also turn off ARPANET traffic, and
the gateway will stop forwarding packets not destined for this host.
Empty input buffers are supplied by the gateway on the list pointed
to by INTFRI. This is the same list that IMPPHY uses to obtain
input buffers from. Filled input buffers are queued on the
main Internet input queue (INTIBI, INTIBO).
Emptied output buffers are put on the INTNFB list for
disposal by INTNRB.
*************** NOTE WELL ****************
RPICHN must be the same as IMPCHN so
that input and output queues and free
lists are properly interlocked.
******************************************
* RPIINI ... 3 ...... Initialization routine
* RPISV ... 3 ...... Main Interrupt dispatch
RPICHK ... 3 ...... Periodic check of interface status
* RPISRT ... 4 ...... Start input
RPII32 ... 5 ...... Input interrupt service
RPIEIN ... 6 ...... End of input message interrupt
RPIXOU ... 7 ...... Start output
RPIO32 ... 8 ...... Output interrupt service
* RPIQOB ... 9 ...... Queue message from gateway for output
!
; Device code:
RPI=554
; Interface CONO/I bits -- BBN standard IMP10 interface:
RPIPWR==1B19 ; Interface power is on
RPIERR==1B22 ; Interface error (incl. not ready)
RPIINB==1B32 ; Word waiting for input
RPIOUB==1B28 ; Word needed for output
RPIEIB==1B24 ; End input
RPIGEB==1B23 ; Program has seen the input end
RPIEOB==1B22 ; Send an end
RPISTO==1B21 ; Stop output
RPIIOF==10B27+10 ; Turn input off (PI assignments)
RPIION==<10+RPICHN>B27+<10+RPICHN> ; Turn input on
RPIOOF==10B31 ; Turn output off
RPIOON==<10+RPICHN>B31 ; Turn output on
; Initialization for Raw Packet Interface
; All queues and lists are initialized by the time this is called.
RPIINI::CONO RPI,RPIIOF!RPIOOF ; Turn it all off
SETZM RPIOB ; Inidicate no output in progress
SETZM RPIIB ; No input either
SETOM INTSCR ; Default to secure mode if this loaded
SKIPE INTNFI ; Any Internet free input buffers around?
JSP T4,RPISRT ; Start initial input
RET
; PI Dispatch (T1, T2, T3, T4, CX and P have been saved.)
RPISV:: CONSO RPI,7 ; Input turned off?
JRST RPISV1 ; Yes
CONSZ RPI,RPIINB
JRST RPII32 ; Word in
CONSZ RPI,RPIEIB
JRST [ CONSO RPI,RPIINB; It can happen that last input came in
JRST RPIEIN ; Within the last few instructions
JRST RPII32] ; If so, handle it first
RPISV1: CONSZ RPI,7B31 ; Do nothing if no channel assigned
CONSO RPI,RPIOUB
RET
SKIPE RPIOB
JRST RPIO32 ; Word out
CONO RPI,RPISTO
RET
; Check to see if RPI input side can be given a new input buffer
RPICHK::SKIPE INTNFI ; Are there input buffers around?
SKIPE RPIIB ; And does RPI need a buffer?
CAIA ; No.
JSP T4,RPISRT ; Yes. Start input on it
RET
; Start input
; called from process level when buffers made available and input is off
; and from endin processor if more buffers are available
RPISRT::CONSZ RPI,RPIPWR ; Interface power on?
CONSZ RPI,RPIERR ; Remote device ready? (ie, no error)
JRST 0(T4) ; No or no. Cannot receive a message.
PIOFF
SOSL INTNFI ; Count one less free input buffer
SKIPN T1,INTFRI ; Get pointer to the first one
INBUG(HLT,<RPISRT: TCP free in buf list fouled>,RPITIF)
LOAD T2,NBQUE,(T1) ; Get next free
SETSEC T2,INTSEC ; Make extended address
MOVEM T2,INTFRI ; That is the head of new free list
PION
SETZRO NBQUE,(T1) ; Unlist from others for cleanliness
MOVEM T1,RPIIB ; Here is the in bfr for the interface
LOAD T2,NBBSZ,(T1) ; Get buffer size from fake IMPDV header
SUBI T2,PKTELI-IMP96L ; Number of words in packet
MOVEM T2,RPIICT ; Set number of 32-bit inputs to do
ADDI T1,PKTELI-IMP96L-1 ; Bump addr part up to Internet part -1
MOVEM T1,RPIINP ; Here is the input pointer
MOVSI T1,-↑D8 ; Init 36-32 bit state word
MOVEM T1,RPIS32
CONO RPI,RPIION+1B19 ; Clear error and start input
JRST 0(T4)
; Pi service for input
RPII32: CONI RPI,T4 ; Get state of END-IN bit for later
DATAI RPI,T1 ; Get the data word
EXCH T4,RPIINP ; Get ptr to input buffer
SKIPG RPIICT ; More space to be filled in packet?
JRST RPIEI0 ; Message too big. Just look for end.
MOVE T3,RPIS32 ; Get unpacking state word
TRNE T3,777777 ; Previous word already full?
JRST RPI32A ; No
SOS RPIICT ; Yes, skip to the next one
AOS T4 ; Advance storage address also
RPI32A: LSHC T1,@RPISHT(T3) ; Align input bytes with destination
DPB T1,RPIPT1(T3) ; High order byte for n-th word
MOVEM T2,1(T4) ; Low order byte for n+1st word
AOBJN T3,RPI32B ; Step state
MOVSI T3,-↑D8 ; Reinit state word
RPI32B: MOVEM T3,RPIS32 ; Save state
AOS T4 ; Bump storage address
SOSG RPIICT ; Count down space left
JRST RPIEI0 ; Handle full buffer
MOVEM T4,RPIINP ; Save bfr ptr
UNBRK RPI
; Tables for 36-32 bit conversion, indexed by state word
RPISHT: XX==4
REPEAT ↑D8,<Z -XX
XX=XX+4
>
RPIPT1: XX==↑D32
REPEAT ↑D8,<POINT XX,0(T4),31
XX=XX-4
>
; Here when end msg recd from interface
RPIEI0: EXCH T4,RPIINP ; Save pointer. Get CONI.
TRNN T4,RPIEIB ; Also end input?
JRST RPIEIX ; End not received on big msg
RPIEIN: CONO RPI,RPIGEB ; Got end bit.
MOVE T1,RPIIB ; Buffer address
XMOVEI T2,-IMP96L(T1) ; Form TCP-style packet pointer
SETONE PSCR,(T2) ; Set the interface class (secure)
LOAD T3,PIVER,(T2) ; Internet Version
CAIN T3,.INTVR ; Right?
JRST RPIEI1 ; Yes. Take it
MOVE T2,T1 ; Copy address for indexing
EXCH T1,INTFRI ; Make it be head of free list
STOR T1,NBQUE,(T2) ; Tack old list onto this bfr
AOS INTNFI ; Count it up
JRST RPIEI2 ; Restart input
RPIEI1: LOAD T2,NBBSZ,(T1) ; Number of words in buffer
ADDI T1,-1(T2) ; Last word in buffer
CALL MULKMP ; Unlock tail. RCVGAT does the head.
MOVE T1,RPIIB ; Bfr address
MOVE T3,RPIINP ; Last word with data
SUBI T3,-1(T1) ; End-(Start-1)=Amount present
STOR T3,NBBSZ,(T1) ; Record actual count in buffer header
MOVE T3,INTIBI ; Add to gateway input queue
JUMPN T3,RPIEI3 ; Queue was not empty
MOVEM T1,INTIBO ; Only thing on the queue is new thing
SKIPA ; Dont try to link it
RPIEI3: STOR T1,NBQUE,(T3) ; Link to others on queue
MOVEM T1,INTIBI ; New buf is last thing on queue
AOS INTFLG ; Cause the TCP to see this new input
RPIEI2: SETZM RPIIB ; Now no input buffer
CONO RPI,RPIIOF ; Turn off input PIs
SKIPE INTFRI ; More buffers available?
JSP T4,RPISRT ; Yes, start new input
RPIEIX: UNBRK RPI
; Routine to start msg going out. Called at PI level, and at
; main level (PIOFF) if no output in progress
RPIXOU: SKIPN T1,RPIOBO ; Msg waiting to go out?
JRST 0(T4) ; Return if not
LOAD T2,NBQUE,(T1) ; Get bfr's successor
SKIPN T2 ; If last,
SETZM RPIOBI ; Clear the queue
SETSEC T2,INTSEC ; Make extended address
MOVEM T2,RPIOBO ; Update output pointer
SETZRO NBQUE,(T1) ; Unlist from others for cleanliness
MOVEM T1,RPIOB ; Buffer in 1 is now to go out
LOAD T2,NBBSZ,(T1) ; Count of data words
SUBI T2,PKTELI-IMP96L-1 ; Skip local ldr. DATAO does 1st word
MOVEM T2,RPIOCT ; Number of 32-bit outputs in RPIO32
ADDI T1,PKTELI-IMP96L ; Bump address upto internet part
MOVEM T1,RPIOUP ; Pointer for interrupts
MOVE T2,1(T1) ; Get second word
MOVE T1,0(T1) ; Get first word
LSH T1,-4 ; Abut with 1-st word
LSHC T1,4 ; Put it together to get 1st 36 bits
MOVE T2,[-7,,1] ; Initial state word
MOVEM T2,RPOS32
DATAO RPI,T1 ; Send the data to get things going
CONO RPI,RPIOON ; Be sure output PI is enabled
JRST 0(T4)
; PI service for output
; 32-bit output (rest of msg)
RPIO32: SKIPG RPIOCT ; Data left?
JRST RPODN1 ; No
MOVE T3,RPOS32 ; Get state word
AOS T4,RPIOUP ; Inc bfr ptr
SOSLE RPIOCT ; Count down number left
MOVE T2,1(T4) ; Get n+1th word
MOVE T1,0(T4) ; Get nth word
LSH T1,-4 ; Align high-order byte
LSHC T1,@RPOSHT(T3) ; Shift bytes into output word
DATAO RPI,1
AOBJN T3,RPO32B ; Step state
AOS T4 ; Extra inc of bfr each cycle
SOS RPIOCT
MOVSI T3,-↑D8 ; Reinit state word
RPO32B: MOVEM T3,RPOS32 ; Save state word
MOVEM T4,RPIOUP ; Save bfr ptr
UNBRK RPI
RPODN1: SKIPGE T1,RPIOB ; Get buffer location
JRST RPODN2 ; Sent done bit. Now start next xfer.
MOVE T2,T1 ; Copy pointer for index use
EXCH T1,INTNFB ; Put bfr back on free list
STOR T1,NBQUE,(T2)
HRROS T1,RPIOB ; Set flag for next interrupt
CALL IMULKB ; Unlock both ends of the buffer
CONO RPI,RPIEOB ; Sent last word, now send end bit
UNBRK RPI
RPODN2: SETZM RPIOB
JSP T4,RPIXOU ; Start next msg if any
UNBRK RPI
; Table for 32-36 bit conversion, indexed by state word
RPOSHT: XX==4
REPEAT ↑D8,<Z XX
XX=XX+4
>
; Queue a TCP packet for output on the Raw Packet Interface.
; Called from the gateway.
;T2/ "IMPDV" style packet pointer (already locked)
;
; CALL RPIQOB
;Ret+1: Packet not queued. Interface is not up etc.
;Ret+2: RPI will take packet and return storage via INTNRB
RPIQOB::PIOFF ; Grab the queue pointers
SETZRO NBQUE,(T2) ; Clean up list pointer from others
SKIPE T1,RPIOBI ; Is queue currently empty?
JRST RPIQO3 ; No. Dont set output pointer
MOVEM T2,RPIOBO ; This is the only item
SKIPA
RPIQO3: STOR T2,NBQUE,(T1) ; Add to tail
MOVEM T2,RPIOBI
SKIPN RPIOB ; Is there output in progress?
JSP T4,RPIXOU ; No. Start it up.
PION
AOS (P)
RET
TNXEN